#coding=utf-8

import wx, threading, Queue,time
import tree2
from pyExcelerator import *
from config import *
from fetcher import *

def get_SuggestTreeRoot(query, fetch, parent=None, 
                        result_list=None, output_window=None):
    
    result_list.append(query)
    root = tree2.Node(data=query, parent=parent)
    
    data = fetch(query)
    
    if not data:return root
    
    for d in data:
        if result_list and (d in result_list):continue
        print d 
        if output_window:
            #print d
            wx.CallAfter(output_window.LogMessage, d)
        t = get_SuggestTreeRoot(d, fetch, root, result_list, output_window)
        root.add_child(t)
        
    return root

def get_SuggestTree(query, fetch, output_window=None):
    rl = []
    root = get_SuggestTreeRoot(query, fetch, None, rl, output_window)
    return tree2.Tree(root)

def sparse2sheet(sp, sheet, origin=(0,0)):
    mx, my = sp.size()
    x0, y0 = origin
    for x in range(mx):
        for y in range(my):
            data = sp.get((x,y))
            if data:
                sheet.write(y0+y, x0+x, data)

def list2sheet(list_, sheet, origin_y=0):
    i = 0
    for data in list_:
        sheet.write(i, origin_y, data)
        i = i + 1

class FetchThread(threading.Thread):
    
    def __init__(self, fetcher, result_dict, queue, window):
        threading.Thread.__init__(self)
        
        self.fetcher = fetcher
        
        self.result_dict = result_dict
        self.window = window
        self.queue = queue
        
    def run(self):
        while True:
            query = self.queue.get()
            
            sgt = get_SuggestTree(query, self.fetcher, output_window=self.window)
            if sgt.root.children:
                self.result_dict[query] = sgt
            
            self.queue.task_done()
            
            time.sleep(0.05)

class NotifyThread(threading.Thread):
    
    def __init__(self, queue, parent): 
        
        threading.Thread.__init__(self)
        self.queue = queue
        self.parent = parent
        
    def run(self):
        self.queue.join()
        wx.CallAfter(self.parent.QueueFinished)
        
az = [chr(i)for i in range(97,123)]
aazz = [i+j for i in az for j in az]    
def get_querys(kw):
    r = [kw,]
    for i in az:r.append(' '.join([kw, i]))
    #for i in aazz:r.append(' '.join([kw, i]))
    return r
    
class MainFrame(wx.Frame):
    
    def __init__(self):
        wx.Frame.__init__(self, None, -1, 'SuggestFetcher', 
                size=(600, 450))
        panel = wx.Panel(self, -1)
        
        sizer = wx.GridBagSizer(hgap=4, vgap=5)
        
        self.st = wx.StaticText(panel, -1, label=unicode('请输入关键词:', 'u8'))
        sizer.Add(self.st, pos=(0, 0), flag=wx.TOP|wx.RIGHT, border=5)
        
        self.tc = wx.TextCtrl(panel, -1, "harvard", 
                size=(240, -1))
        self.tc.SetInsertionPoint(0)
        sizer.Add(self.tc, pos=(0, 1), flag=wx.TOP, border=5)
        
        self.bt_config = wx.Button(panel, -1, unicode('设置', 'u8'))
        self.Bind(wx.EVT_BUTTON, self.OnConfig, self.bt_config)
        sizer.Add(self.bt_config, pos=(0, 2), flag=wx.TOP, border=5)
        
        self.bt_search = wx.Button(panel, -1, unicode('搜索', 'u8'))
        self.Bind(wx.EVT_BUTTON, self.OnSearch, self.bt_search)
        sizer.Add(self.bt_search, pos=(0, 3), flag=wx.TOP, border=5)
        
        self.mt = wx.TextCtrl(panel, -1,
                    size = (520, 360),
                    style=wx.TE_MULTILINE|wx.TE_READONLY)
        sizer.Add(self.mt, pos=(1, 0),span=(3,4) )
        
        panel.SetSizer(sizer)
        
    def OnConfig(self, event):
        cd = ConfigDialog(self)
        if cd.ShowModal() == wx.ID_OK:
            cd.update_options()
        cd.Destroy()
        
    def OnSearch(self,event):
        self.mt.Clear()
        
        self.workbook = Workbook()
        
        self.keywords = [k.strip()for k in self.tc.GetValue().split(',')]
        self.fetchers = list(options.search_engines_chosed)
        
        self.current_fetcher = self.fetchers.pop(0)    
        self.current_keyword = self.keywords.pop(0)
        
        queue = Queue.Queue()
        for q in get_querys(self.current_keyword):
            queue.put(q)
        
        self.result_dict = {}
        self.result_list = []
        
        for i in range(options.thread_num):
            t = FetchThread(eval(self.current_fetcher), self.result_dict, 
                            queue=queue, window=self)   
            t.setDaemon(True)
            t.start()
            
        nt = NotifyThread(queue, self)
        nt.setDaemon(True)
        nt.start()   
               
    def LogMessage(self, msg):
       
        self.mt.AppendText('%s\n'%msg)
    
    def QueueFinished(self):
    
        sheet = self.workbook.add_sheet(self.current_fetcher)
        rdict2sheet(self.result_dict, sheet)
        
        rlist = []
    
        keys = self.result_dict.keys()
        keys.sort()
    
        for k in keys:
            rlist.append(self.result_dict[k])
    
        st = rlist.pop(0)
        self.result_list.extend(st.toList())
        for st in rlist:
            self.result_list.extend(st.toList()[1:])    
            
        if self.fetchers:
            
            self.current_fetcher = self.fetchers.pop(0)    
            
            queue = Queue.Queue()
            for q in get_querys(self.current_keyword):
                queue.put(q)
            
            self.result_dict = {}
                
            for i in range(options.thread_num):
                t = FetchThread(eval(self.current_fetcher), self.result_dict, 
                                queue=queue, window=self)   
                t.setDaemon(True)
                t.start()
                    
         
            nt = NotifyThread(queue, self)
            nt.setDaemon(True)
            nt.start()
            
        else:
            sheet_all = self.workbook.add_sheet('all_items')
            list2sheet(list(set(self.result_list)), sheet_all)
            
            fn = os.path.join(options.datadir, '%s.xls'%self.current_keyword)
            self.workbook.save(fn)       
            
            self.result_list = []
            if self.keywords:
                #self.mt.Clear()
                self.workbook = Workbook()
                
                self.fetchers = list(options.search_engines_chosed)
                self.current_fetcher = self.fetchers.pop(0)
                self.current_keyword = self.keywords.pop(0)
                    
                queue = Queue.Queue()
                for q in get_querys(self.current_keyword):
                    queue.put(q)
                
                self.result_dict = {}
                    
                for i in range(options.thread_num):
                    t = FetchThread(eval(self.current_fetcher), self.result_dict, 
                                    queue=queue, window=self)   
                    t.setDaemon(True)
                    t.start()
                    
                nt = NotifyThread(queue, self)
                nt.setDaemon(True)
                nt.start()
            else:
                message_dlg = wx.MessageDialog(None, unicode('查询成功!', 'u8'),
                          'A Message Box',
                          wx.OK)
                message_dlg.ShowModal()
                
def rdict2sheet(rdict, sheet):
    rlist = []
    
    keys = rdict.keys()
    keys.sort()
    
    for k in keys:
        rlist.append(rdict[k])
    
    l = []
    
    x = 2; y = 0
    st = rlist.pop(0)
    l.extend(st.toList())
    sp = st.toSparse()
    sparse2sheet(sp, sheet, (x,y))
    y = y + sp.size()[1] + 1
    
    for st in rlist:
        #print x
        l.extend(st.toList()[1:])        
        sp = st.toSparse()
        sparse2sheet(sp, sheet, (x,y)) 
        y = y + sp.size()[1] + 1
    
    #print l
    l = list(set(l))
    list2sheet(l, sheet)
    
if __name__ == '__main__':
    app = wx.PySimpleApp()
    frame = MainFrame()
    frame.Show()
    app.MainLoop()
